package br.com.news.business;

import java.io.StringWriter;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

import br.com.news.business.utils.GenericBusiness;
import br.com.news.business.utils.VelocityTemplateFactory;
import br.com.news.utils.DateUtil;
import br.com.news.utils.business.exception.BusinessException;
import br.com.news.utils.business.interfaces.IAuditoriaBusiness;
import br.com.news.utils.business.interfaces.INoticiaBusiness;
import br.com.news.utils.database.beans.NoticiaBean;
import br.com.news.utils.database.exception.DataBaseServiceException;
import br.com.news.utils.database.interfaces.INoticiaServiceDb;
import br.com.news.utils.interfaces.Constantes;

@Named
public class NoticiaBusiness extends GenericBusiness implements INoticiaBusiness {

	private static final String AUDITORIA_NOTICIA = "NOTICIA";
	
	@Inject
	private INoticiaServiceDb noticiaServiceDb;
	
	@Inject
	private IAuditoriaBusiness auditoriaBusiness;
	
	@Inject
	private VelocityTemplateFactory velocity;

	@Override
	public List<NoticiaBean> findAll() throws BusinessException {
		try {
			return noticiaServiceDb.findAll();
		} catch (DataBaseServiceException e) {
			throw new BusinessException(e);
		}
	}

	@Override
	public List<NoticiaBean> lastNews(int qntNoticias,long idNoticia, long idCategoria) throws BusinessException{
		try {
			if (idCategoria > 0 ){ 
				if(idNoticia > 0){
					return noticiaServiceDb.getNoticiasAnteriores(qntNoticias, idNoticia, idCategoria);
				}else{
					return noticiaServiceDb.getUltimasNoticias(qntNoticias, idCategoria);
				}
			} 
			else {
				if(idNoticia > 0){
					return noticiaServiceDb.getNoticiasAnterioresXml(qntNoticias, idNoticia);
				}else{
					return noticiaServiceDb.getUltimasNoticiasXml(qntNoticias);
				}
			}
		} catch (DataBaseServiceException e) {
			throw new BusinessException(e);
		}
	}
	
	@Override
	public Long save(NoticiaBean noticia) throws BusinessException {
		try {
			long id = noticiaServiceDb.save(noticia);
			auditoriaBusiness.save(noticia.getUsuario(), id, AUDITORIA_NOTICIA);
			return id;
		} catch (DataBaseServiceException e) {
			throw new BusinessException("Erro ao tentar salvar a noticia", e);
		}
	}
	
	@Override
	public void update(NoticiaBean noticia) throws BusinessException {
		try {
			noticiaServiceDb.update(noticia);
			auditoriaBusiness.save(noticia.getUsuario(), noticia.getIdNoticia(), AUDITORIA_NOTICIA);
		} catch (DataBaseServiceException e) {
			throw new BusinessException("Erro ao tentar alterar a noticia", e);
		}
	}

	public boolean existeNoticia(NoticiaBean noticiaBean) {
		return noticiaServiceDb.existeNoticia(noticiaBean);
	}

	@Override
	public List<NoticiaBean> lastNews(long idNoticia, long idCategoria)
			throws BusinessException {
		try {
			return noticiaServiceDb.findLastNews(idNoticia, idCategoria);
		} catch (DataBaseServiceException e) {
			throw new BusinessException(e);
		}
	}
	
	@Override
	public NoticiaBean findNoticiaById(Long id) throws BusinessException {
		try {
			return noticiaServiceDb.findById(id);
		} catch (DataBaseServiceException e) {
			throw new BusinessException(e);
		}
	}
	
	@Override
	public Long quantidadePaginas(long idCategoria) {
		return noticiaServiceDb.quantidadePaginas(idCategoria);
	}
	
	@Override
	public List<NoticiaBean> findNoticiasPorPagina(int linha,Long idCategoria,int quantidade) {
		return noticiaServiceDb.findNoticiasPorPagina(linha, idCategoria,quantidade);
	}
	
	@Override
	public List<NoticiaBean> buscaNoticiaPorNome(String nome) {
		return noticiaServiceDb.buscaNoticiaPorNome(nome);
	}

	@Override
	public List<NoticiaBean> findByExample(NoticiaBean noticiaBean) {
		return noticiaServiceDb.findByExample(noticiaBean);
	}

	@Override
	public String returnTextNew(long idNoticia) throws BusinessException {
		try {
			NoticiaBean noticiaBean = noticiaServiceDb.findById(idNoticia);
			if (!noticiaBean.getFonte().getDescricao().equals(Constantes.DESCRICAO_FONTE_VARIUS)) {
				return geraConteudoPagina(noticiaBean, noticiaBean.getTexto());
			} else {
				return geraConteudoPagina(noticiaBean, geraConteudoCorpo(noticiaBean));
			}
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}
	
	@Override
	public NoticiaBean findImageByIdNoticia(Long idNoticia) throws BusinessException {
		try {
			return noticiaServiceDb.findImageByIdNoticia(idNoticia);
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}
	
	private String geraConteudoPagina(NoticiaBean noticiaBean, String texto) throws Exception {
		Template template = velocity.getTemplate("paginaCompleta.vm");
		
		VelocityContext context = new VelocityContext();
		context.put("dataNoticia", DateUtil.convert(noticiaBean.getDataNoticia()));
		context.put("titulo", noticiaBean.getTitulo());
		context.put("subtitulo", noticiaBean.getSubTitulo());
		context.put("autor", noticiaBean.getAutor() == null ? "" : noticiaBean.getAutor());
		context.put("fonte", noticiaBean.getFonte().getDescricao());
        context.put("corpo", texto);
        
        StringWriter writer = new StringWriter();
        template.merge(context, writer);
        
        return writer.toString();
	}
	
	private String geraTagImage(NoticiaBean noticiaBean) throws Exception {
		Template template = velocity.getTemplate("imagem.vm");

		VelocityContext context = new VelocityContext();
		context.put("idNoticia", noticiaBean.getIdNoticia());
		StringWriter writer = new StringWriter();
		template.merge(context, writer);

		return writer.toString();
	}
	
	private String geraConteudoCorpo(NoticiaBean noticiaBean) throws Exception {
		Template template = velocity.getTemplate("paginaTemplate.vm");
		
		VelocityContext context = new VelocityContext();
		if (noticiaBean.getImagem() != null){
			context.put("imagem", geraTagImage(noticiaBean));
		} else {
			context.put("imagem", "");
		}
        
        context.put("texto", noticiaBean.getTexto());
        
        StringWriter writer = new StringWriter();
        template.merge(context, writer);
        
        return writer.toString();
	}
}
